﻿using Polly;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Shura.Util.WinkFault
{
    public static class WinkFault
    {
        private static int lll = 0;
        public static void Execute()
        {
            var retry = Policy.Handle<Exception>()
                .Retry(3, (ex, i, context) => {
                    Console.WriteLine("retry" + i);
                });
            var breaker  = Policy.Handle<Exception>()
                .CircuitBreaker(2, TimeSpan.FromSeconds(10));
            var timeout = Policy
                .Timeout(12, onTimeout: (context, timespan, task) =>
                {
                    Console.WriteLine("Timeout" + timespan.TotalSeconds);
                });

            var ll = Policy.Wrap(retry, breaker, timeout);
            //var ll = Policy.Handle<Exception>()
            //        //.Retry(3, (ex, i,context) => {
            //        //    Console.WriteLine(i);
            //        //});
            //        //.WaitAndRetry(new[] {
            //        //    TimeSpan.FromSeconds(10),
            //        //    TimeSpan.FromSeconds(20),
            //        //    TimeSpan.FromSeconds(30),
            //        //}, (ex, i, context) =>
            //        //{
            //        //    Console.WriteLine(DateTime.Now.ToString("HHmmss"));
            //        //})
            //        .CircuitBreaker(2, TimeSpan.FromSeconds(10));

            TaskFactory taskFactory = new TaskFactory();
            taskFactory.StartNew(()=> {
                var key = "t1";
                try
                {
                    ll.Execute<int>(() => {
                        return GetNum2(key);
                    });
                }
                catch
                {
                    Console.WriteLine("ex" + lll);
                }
                Console.WriteLine("hhh");
            });
        }

        public async static Task<int> GetNum()
        {
            Console.WriteLine("getnum2start");
            if (lll++ < 2)
            {
                throw new ArgumentNullException();
                Console.WriteLine("getnum2end1");
            }
            else
            {
                Console.WriteLine("getnum2end");
            }
            await Task.Delay(1000);
            return 1;
        }

        public static int GetNum2(string id)
        {
            Console.WriteLine(id + "getnum2start");
            Thread.Sleep(lll * 1000);
            if (lll++ < 20)
            {
                Console.WriteLine(id + lll);
                throw new ArgumentNullException();
                Console.WriteLine("getnum2end1");
            }
            else
            {
                Console.WriteLine(id +"getnum2end");
            }
            return 1;
        }
    }
}
